#include "Imagine.h"
#include "imPrimitives.h"
#include "imUtils.h"
#include "ObjFile.h"

#include "DIKeys.h"

#include <Config.h>

using namespace imGraphics;
using namespace imInput;

// I have the source files to every Quake 1 level, for use as test assets!
// Here's how to parse the files http://www.modwiki.net/wiki/MAP_%28file_format%29
// Remember that while lightmaps don't need to be baked in Imagine, the maps
// still need VIS information for efficient viewing!

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, char * lpCmdLine, int nCmdShow) {
	Config cfg("config.cfg");

	RendererLib GfxLib;
	GfxLib.MountLib("GfxD3D9.dll");

	InputLib Inp(hInstance);
	Inp.MountLib("InDI8.dll");

	imGraphics::imWindow MyWin;
	MyWin.ConfigFromFile(&cfg);
	MyWin.SetTitle("Imagine");
	MyWin.Init(hInstance);

	g_GFX->SetupFromFile(&cfg);
	g_GFX->Init(hInstance, MyWin.GetHandle());

	InitDefaultTextures();

	iInputDevice* Kb = Inp.GetDevice(imInput::IN_KEYBOARD);

	Vector3 Pos = Vector3(-9.0, 6.0, -15.0) * 0.5;
	Vector3 LookAt = Vector3();

	Angle LookDir = Angle(LookAt - Pos);

	GraphicsComponent egc;
	egc.SetMesh(new Mesh("mclarenf1.sms"));

	iEntity Ent;
	Ent.AddComponent(&egc);
	Ent.SetMovementComponent(new StaticMovementCmp());

	GraphicsComponent ggc;
	ggc.SetMesh(new Mesh(Grid(2.0f, 10, 10)));

	iEntity Grnd;
	Grnd.AddComponent(&ggc);
	Grnd.SetMovementComponent(new StaticMovementCmp());

	Grnd.SetPos(Vector3(-9.0f, -0.6f, -9.0f));

	g_GFX->SetViewMatrix(Matrix::View(Pos, LookDir));
	g_GFX->SetWorldMatrix(Matrix::World(LookAt, Angle()));

	Clock Cl;

	// Running
    MSG msg; 
    ZeroMemory(&msg, sizeof(msg));
    while(msg.message!=WM_QUIT)
    {
		if(PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE)) {
			TranslateMessage(&msg);
            DispatchMessage(&msg);
		} else {
			// Main
			Cl.Update();

			// View stuff
			Pos = Angle(0.0f, Cl.GetTime() * 0.4f, 0.0f).Forward() * 8.0f;
			Pos.y = 3.0;

			Kb->Update();
			if(Kb->KeyDown(DIK_W))
				Pos.y = 2.0;

			LookDir = Angle(LookAt - Pos);
			g_GFX->SetViewMatrix(Matrix::View(Pos, LookDir));

			//Frame stuff
			g_GFX->StartFrame();

			for each(iComponent* c in g_Comps)
				c->Update();

			g_GFX->EndFrame();

			Sleep(0);
		}
    }

	g_GFX->Release();

	return 0;
};